package com.datatrans;

import com.datatrans.config.TransferConfig;
import com.datatrans.service.DataTransferService;
import com.datatrans.exception.TransferException;

import java.util.Arrays;
import java.util.List;

/**
 * 数据库表数据迁移工具主类
 * 支持命令行参数配置
 */
public class App {
    
    public static void main(String[] args) {
        // 检查是否有帮助参数
        for (String arg : args) {
            if ("--help".equals(arg) || "-h".equals(arg)) {
                printHelp();
                return;
            }
        }
        
        try {
            // 解析命令行参数
            TransferConfig config = parseArguments(args);
            
            // 执行数据迁移
            DataTransferService service = new DataTransferService();
            service.transfer(config);
            
            System.out.println("数据迁移完成！");
        } catch (TransferException e) {
            System.err.println("数据迁移失败: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("程序执行出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    private static void printHelp() {
        System.out.println("数据库表数据迁移工具 - 命令行模式");
        System.out.println("使用方法:");
        System.out.println("  java -jar data-transfer-1.0-SNAPSHOT-jar-with-dependencies.jar [选项]");
        System.out.println("");
        System.out.println("选项:");
        System.out.println("  -h, --help                显示帮助信息");
        System.out.println("  -sourceUrl <url>          源数据库连接URL");
        System.out.println("  -sourceUsername <user>    源数据库用户名");
        System.out.println("  -sourcePassword <pass>    源数据库密码");
        System.out.println("  -sourceDbType <type>      源数据库类型(MYSQL/POSTGRESQL)");
        System.out.println("  -targetUrl <url>          目标数据库连接URL");
        System.out.println("  -targetUsername <user>    目标数据库用户名");
        System.out.println("  -targetPassword <pass>    目标数据库密码");
        System.out.println("  -targetDbType <type>      目标数据库类型(MYSQL/POSTGRESQL)");
        System.out.println("  -sourceTable <tables>     源表名(多个表用逗号分隔)");
        System.out.println("  -targetTable <tables>     目标表名(多个表用逗号分隔)");
        System.out.println("  -mode <mode>              迁移模式(DELETE_THEN_COPY/UPDATE/IGNORE)");
        System.out.println("");
        System.out.println("示例:");
        System.out.println("  java -jar data-transfer-1.0-SNAPSHOT-jar-with-dependencies.jar \\");
        System.out.println("    -sourceUrl jdbc:mysql://localhost:3306/source_db \\");
        System.out.println("    -sourceUsername root \\");
        System.out.println("    -sourcePassword password \\");
        System.out.println("    -sourceDbType MYSQL \\");
        System.out.println("    -targetUrl jdbc:postgresql://localhost:5432/target_db \\");
        System.out.println("    -targetUsername postgres \\");
        System.out.println("    -targetPassword password \\");
        System.out.println("    -targetDbType POSTGRESQL \\");
        System.out.println("    -sourceTable users \\");
        System.out.println("    -mode DELETE_THEN_COPY");
    }
    
    /**
     * 解析命令行参数
     */
    private static TransferConfig parseArguments(String[] args) throws TransferException {
        TransferConfig config = new TransferConfig();
        
        // 解析参数
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
            
            switch (arg) {
                case "-sourceUrl":
                    if (i + 1 < args.length) {
                        config.setSourceUrl(args[++i]);
                    } else {
                        throw new TransferException("缺少源数据库URL参数");
                    }
                    break;
                    
                case "-sourceUsername":
                    if (i + 1 < args.length) {
                        config.setSourceUsername(args[++i]);
                    } else {
                        throw new TransferException("缺少源数据库用户名参数");
                    }
                    break;
                    
                case "-sourcePassword":
                    if (i + 1 < args.length) {
                        config.setSourcePassword(args[++i]);
                    } else {
                        throw new TransferException("缺少源数据库密码参数");
                    }
                    break;
                    
                case "-sourceDbType":
                    if (i + 1 < args.length) {
                        String dbType = args[++i].toUpperCase();
                        try {
                            config.setSourceDbType(TransferConfig.DatabaseType.valueOf(dbType));
                        } catch (IllegalArgumentException e) {
                            throw new TransferException("不支持的源数据库类型: " + dbType);
                        }
                    } else {
                        throw new TransferException("缺少源数据库类型参数");
                    }
                    break;
                    
                case "-targetUrl":
                    if (i + 1 < args.length) {
                        config.setTargetUrl(args[++i]);
                    } else {
                        throw new TransferException("缺少目标数据库URL参数");
                    }
                    break;
                    
                case "-targetUsername":
                    if (i + 1 < args.length) {
                        config.setTargetUsername(args[++i]);
                    } else {
                        throw new TransferException("缺少目标数据库用户名参数");
                    }
                    break;
                    
                case "-targetPassword":
                    if (i + 1 < args.length) {
                        config.setTargetPassword(args[++i]);
                    } else {
                        throw new TransferException("缺少目标数据库密码参数");
                    }
                    break;
                    
                case "-targetDbType":
                    if (i + 1 < args.length) {
                        String dbType = args[++i].toUpperCase();
                        try {
                            config.setTargetDbType(TransferConfig.DatabaseType.valueOf(dbType));
                        } catch (IllegalArgumentException e) {
                            throw new TransferException("不支持的目标数据库类型: " + dbType);
                        }
                    } else {
                        throw new TransferException("缺少目标数据库类型参数");
                    }
                    break;
                    
                case "-sourceTable":
                    if (i + 1 < args.length) {
                        String sourceTables = args[++i];
                        // 支持多个源表，用逗号分隔
                        String[] tables = sourceTables.split(",");
                        for (String table : tables) {
                            table = table.trim();
                            if (!table.isEmpty()) {
                                config.addTableMapping(table); // 目标表默认等于源表
                            }
                        }
                    } else {
                        throw new TransferException("缺少源表名参数");
                    }
                    break;
                    
                case "-targetTable":
                    if (i + 1 < args.length) {
                        String targetTables = args[++i];
                        // 支持多个目标表，用逗号分隔
                        String[] tables = targetTables.split(",");
                        for (int j = 0; j < tables.length; j++) {
                            String table = tables[j].trim();
                            if (!table.isEmpty()) {
                                // 更新对应位置的表映射
                                List<TransferConfig.TableMapping> mappings = config.getTableMappings();
                                if (j < mappings.size()) {
                                    mappings.get(j).setTargetTable(table);
                                } else {
                                    // 如果还没有对应的源表映射，创建一个新的
                                    config.addTableMapping(table, table);
                                }
                            }
                        }
                    } else {
                        throw new TransferException("缺少目标表名参数");
                    }
                    break;
                    
                case "-mode":
                    if (i + 1 < args.length) {
                        String mode = args[++i].toUpperCase();
                        try {
                            config.setTransferMode(TransferConfig.TransferMode.valueOf(mode));
                        } catch (IllegalArgumentException e) {
                            throw new TransferException("不支持的迁移模式: " + mode);
                        }
                    } else {
                        throw new TransferException("缺少迁移模式参数");
                    }
                    break;
                    
                default:
                    throw new TransferException("不支持的参数: " + arg);
            }
        }
        
        // 验证必需参数
        validateConfig(config);
        
        return config;
    }
    
    /**
     * 验证配置参数
     */
    private static void validateConfig(TransferConfig config) throws TransferException {
        if (config.getSourceUrl() == null || config.getSourceUrl().isEmpty()) {
            throw new TransferException("源数据库URL不能为空");
        }
        
        if (config.getSourceUsername() == null || config.getSourceUsername().isEmpty()) {
            throw new TransferException("源数据库用户名不能为空");
        }
        
        if (config.getSourceDbType() == null) {
            throw new TransferException("源数据库类型不能为空");
        }
        
        if (config.getTargetUrl() == null || config.getTargetUrl().isEmpty()) {
            throw new TransferException("目标数据库URL不能为空");
        }
        
        if (config.getTargetUsername() == null || config.getTargetUsername().isEmpty()) {
            throw new TransferException("目标数据库用户名不能为空");
        }
        
        if (config.getTargetDbType() == null) {
            throw new TransferException("目标数据库类型不能为空");
        }
        
        if (config.getTableMappings().isEmpty()) {
            throw new TransferException("至少需要配置一个表映射");
        }
        
        if (config.getTransferMode() == null) {
            throw new TransferException("迁移模式不能为空");
        }
    }
}